package fourWins;

public class Game implements FourWins, TicTacToe {

	private Result result;
	private Chip[][] field; 
	private int row;
	private int column;

	private int winCount;
	
	public Game(int row, int column) {
		this.row = row;
		this.column = column;
		this.winCount = 4;
		if(row == 3 && column == 3) {
			this.winCount = 3;
		}
		this.result = new Result();
		field = new Chip[row][column];
		for(int i = 0; i < field.length; i++) {
			for(int j = 0; j < field[i].length; j++) {
				field[i][j] = new Chip(0);
			}
		}
	}

	
	@Override
	public Result throwChip(Chip chip, int column) {
		
		int[] position = this.throwInColumn(column, chip);
		result.setWinner(checkWinner(position));
		
		return result;
	}
	
	private int checkWinner(int[] pos) {		
		int player = field[pos[0]][pos[1]].getPlayer();
		if(winCheckVertical(pos)) {
			return player;
		}
		if(winCheckHorizontal(pos)) {
			return player;
		}
//		if(winCheckDiagonal1(pos)) {
//			return player;
//		}
//		if(winCheckDiagonal2(pos)) {
//			return player;
//		}
		return 0;
	}
	
	private Boolean winCheckDiagonal1(int[] pos) {
		int player = field[pos[0]][pos[1]].getPlayer();
		int counter = 0;
		int toLeft = 3;
		int toRight = 3;
		if(pos[1] < 3 || pos[0] < 3) {
			if(pos[1] < pos [0]) {
				toLeft = pos[1];
			} else {
				toLeft = pos[0];
			}
		}
		if((6-pos[1]) < 3 || (5-pos[0]) < 3) {
			if((6-pos[1]) < (5-pos[0])) {
				toRight = (6-pos[1]);
			} else {
				toRight = (5-pos[0]);
			}
		}
		int min[] = {pos[0]-toLeft, pos[1]-toLeft};
		
		
		for(int i=0; i<=toLeft+toRight; i++) {
			if(player == field[(min[0]+i)][(min[1]+i)].getPlayer()) {
				counter++;
				if(4 == counter) {
					return true;
				}
			} else {
				counter = 0;
			}
		}
		return false;
	}
	
	private Boolean winCheckDiagonal2(int[] pos) {
		int player = field[pos[0]][pos[1]].getPlayer();
		int counter = 0;
		int toLeft = 3;
		int toRight = 3;
		if(pos[1] < 3 || (5-pos[0]) < 3) {
			if(pos[1] < (5-pos[0])) {
				toLeft = pos[1];
			} else {
				toLeft = (5-pos[0]);
			}
		}
		if((6-pos[1]) < 3 || pos[0] < 3) {
			if((6-pos[1]) < pos[0]) {
				toRight = (6-pos[1]);
			} else {
				toRight = pos[0];
			}
		}
		int min[] = {pos[0]+toLeft, pos[1]-toLeft};
		
		
		for(int i=0; i<=toLeft+toRight; i++) {
			if(player == field[(min[0]-i)][(min[1]+i)].getPlayer()) {
				counter++;
				if(4 == counter) {
					return true;
				}
			} else {
				counter = 0;
			}
		}
		return false;
	}
	
	
	private Boolean winCheckVertical(int[] pos) {
		int player = field[pos[0]][pos[1]].getPlayer();
		int counter = 0;
		int toBottom = (this.winCount-1);
		int toTop = (this.winCount-1);
		int height = field.length - 1;
		if(pos[0] < (this.winCount-1) ) {
			toBottom = pos[0];
		}
		if(pos[0] >= height - (this.winCount-1) ) {
			toTop = height - pos[0];
		}
		int min = pos[0]-toBottom;
		int max = pos[0]+toTop;
		
		for(int i=min; i<=max; i++) {
			if(player == field[i][pos[1]].getPlayer()) {
				counter++;
				if(this.winCount == counter) {
					return true;
				}
			}
		}		
		return false;
	}
	
	private Boolean winCheckHorizontal(int[] pos) {
		int player = field[pos[0]][pos[1]].getPlayer();
		int counter = 0;
		int toLeft = (this.winCount-1);
		int toRight = (this.winCount-1);
		if(pos[1] < (this.winCount-1) ) {
			toLeft = pos[1];
		}
		if(pos[1] >= (field.length - 2) ) {
			toRight = (field.length - 1) - pos[1];
		}
		int min = pos[1]-toLeft;
		int max = pos[1]+toRight;
		
		for(int i=min; i<max; i++) {
			if(player == field[pos[0]][i].getPlayer()) {
				counter++;
				if(this.winCount == counter) {
					return true;
				}
			}
		}		
		return false;
	}

	
	private int[] throwInColumn(int column, Chip chip) {
		for(int i = 0; i < field.length; i++) {
			if(field[i][column].getPlayer() == 0) {
				field[i][column] = chip;
				int[] position = {i,column};
				return position;
			}
		}
		return null;
	}
	
	public void printField(String title) {
		System.out.println("--" + title + "--");
		for(int i = field.length-1; i >= 0; i--) {
			for(int j = 0; j < field[i].length; j++) {
				System.out.print(/*"(" +i+","+j+")" + */field[i][j].getPlayer() + ", ");
			}
			System.out.println();
		}
	}

	@Override
	public Result setChip(Chip chip, int col, int row) {
		int[] position = this.throwInColumn(col,row, chip);
		result.setWinner(checkWinner(position));
		
		return result;
	}
	
	public int[] throwInColumn(int col, int row, Chip chip) {
		if (field[row][col].getPlayer() == 0) {
			field[row][col] = chip;
			int[] position = { row, col };
			return position;
		}

		return null;
	}
	
	
	

}
